// this header will define a list data type (based on python's)
// will be used for complex stuff so it will use a lot of memory
#ifndef LIST_HEADER
#define LIST_HEADER

// this header needs
#include "../../BASIC_TYPES.h"
#include "../ENDIAN.h"
#include "../MEM_ALLOC.h"
// real includes
#include "../ARRAY/CHAR/CHAR_ARR/STRING/STRING.h"
#include "../ARRAY/NUMBER/NUMBER.h"

// enum to be used to generally identify
// the data contained in the node
typedef enum
{
  LNODE_DT_NO_TYPE,
  // integers
  LNODE_DT_UINT8,
  LNODE_DT_UINT16BE,
  LNODE_DT_UINT16LE,
  LNODE_DT_UINT32BE,
  LNODE_DT_UINT32LE,
  LNODE_DT_SINT8,
  LNODE_DT_SINT16BE,
  LNODE_DT_SINT16LE,
  LNODE_DT_SINT32BE,
  LNODE_DT_SINT32LE,
  // floats
  LNODE_DT_FLT16BE,
  LNODE_DT_FLT16LE,
  LNODE_DT_FLT32BE,
  LNODE_DT_FLT32LE,
  LNODE_DT_FLT64BE,
  LNODE_DT_FLT64LE,
  // strings
  LNODE_DT_STR_ASCII,
  LNODE_DT_STR_CP1252,
  LNODE_DT_STR_CP932,
  LNODE_DT_STR_SHIFT_JIS,
  LNODE_DT_STR_UTF8,
  LNODE_DT_STR_UTF16BE,
  LNODE_DT_STR_UTF16LE,
} lnode_data_type;

// list node struct, the foundation block of the list array
struct lnode
{
  // element desc/info
  byte * SRC;           // pointer to the element referenced by in the node
  umax SIZE;            // number of bytes able to be read from SRC
  lnode_data_type TYPE; // integer with the type of data to be read from SRC
  // relations
  struct lnode * BEHIND;  // pointer to the element behind the current node (same level)
  struct lnode * FRONT;   // pointer to the element in front the current node (same level)
  struct lnode * PARENT;  // pointer to the parent of the current node (upper level)
  struct lnode * CHILD;   // pointer to the immediate child of this element (lower level)
  // elemental functions
  umax (* print) (void * src, umax size); // I need to be able to see the element easily somehow
};

// the holy typedef
typedef struct lnode lnode;

// functions to handle a lnodes
lnode * get_lnode(void * src, umax src_size, lnode_data_type type);
// building complex lists functions
lnode * find_lnode_behind(lnode * node, umax index);
lnode * find_lnode_front(lnode * node, umax index);
lnode * find_lnode_parent(lnode * node, umax index);
lnode * find_lnode_child(lnode * node, umax index);
lnode * add_lnode_front(lnode * node, void * src, umax src_size, lnode_data_type type);
lnode * add_lnode_child(lnode * node, void * src, umax src_size, lnode_data_type type);
// deleting a node
lnode * rm_lnode(lnode * node);
// delete direct fronts/childs functions
umax rm_lnode_fronts(lnode * node);
umax rm_lnode_childs(lnode * node);
umax rm_lnode_list(lnode * node);

// other operations on lists
umax count_lnode_fronts(lnode * node);
umax count_lnode_childs(lnode * node);
umax count_lnodes(lnode * node);
umax count_lnodes_parent_lvls(lnode * node);
umax print_lnode_list(lnode * node);

// enum for the search function below
typedef enum
{
  LNODE_DIR_NO_DIR,
  LNODE_DIR_FRONT,
  LNODE_DIR_BEHIND,
  LNODE_DIR_PARENT,
  LNODE_DIR_CHILD,
} lnode_dir;
// specific search function
lnode * find_lnode(lnode * node, lnode_dir dir, umax index);

#include "LIST.c"

#endif // LIST_HEADER
